package org.jeecg.modules.system.aspect;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.jeecg.common.util.SpringContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;


/**
 * 请求日志处理
 *
 * @author yyz
 * @date 2019/11/1
 */
@Aspect
@Order(2)
@Component
public class WebLogAop {

    private static final Logger LOG = LoggerFactory.getLogger(WebLogAop.class);


    private static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
            new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());

    /**
     * 拦截控制器
     */
    //@Pointcut("execution(* org.jeecg.modules.*.controller..*.*(..))")
    @Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
    public void webLog() {
    }


    /**
     * @param joinPoint 切点
     */
    @Before("webLog()")
    public void before(JoinPoint joinPoint) throws Exception {
        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
        MDC.put("requestId", String.valueOf(System.currentTimeMillis()));
        MDC.put("requestUrl", request.getRequestURI());

        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg == null || arg instanceof HttpServletResponse || arg instanceof HttpServletRequest) {
                continue;
            }
            try {
                LOG.info("请求参数为:" + JSON.toJSONString(arg));
            } catch (Exception e) {
                e.printStackTrace();
                LOG.error("请求参数转换json失败");
            }
        }
    }

    /**
     * @param ret 控制器返回对象
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void afterReturn(Object ret) {
        String requestId = MDC.get("requestId");
        String interval = "";
        if (StringUtils.isNotBlank(requestId)) {
            Long startTime = Long.valueOf(requestId);
            Long endTime = System.currentTimeMillis();
            interval = "处理时间:" + (endTime - startTime) + "ms";
        }
        LOG.info(interval + "   响应数据为:" + JSON.toJSONString(ret));
        MDC.clear();
    }
}
